<?php
/*
 * @Description    : 
 * @Version        : 1.0.0
 * @Author         : QianLong
 * @Date           : 2020-02-08 15:01:43
 * @LastEditors    : QianLong
 * @LastEditTime   : 2024-01-17 08:41:49
 */

declare(strict_types=1);

namespace App\Controller;

use App\Constants\Status;
use App\Exception\ApiException;
use App\Job\SignFailAddJob;
use App\Service\Captcha;
use Qianlong\Validate\Validate;

class CaptchaController extends AbstractController
{
  public function getCaptcha()
  {
    $valitor = new Validate();
    $valitor->addColumn('id')->required();
    if ($valitor && !$this->validate($valitor)) {
      throw new ApiException(Status::CODE_BAD_REQUEST, $valitor->getError()->__toString());
    }
    unset($valitor);
    $param = $this->request->all();
    $where['status'] = 1;
    $where['_id'] = $param['id'];
    $info = mongodb2()->captcha_list->findOne($where);
    $info = json_decode(json_encode($info),true);
    if (isset($info['ak_from']) && $info['ak_from'] == 'platform' && isset($info['ak_id']) && !empty($info['ak_id'])) {
      $akInfo = $this->redisCache->getAk($info['ak_id'], (int)$info['uid']);
      unset($akInfo['_id']);
      $info = array_merge($info, $akInfo);
      unset($akInfo);
    }
    $return = [];
    if (!empty($info)) {
      $return['platform'] = $info['platform'];
      // $http = new HttpRequest;
      switch ($info['platform']) {
        case 'jdcloud':
          $captcha = new Captcha($info);
          $jdPost['appId'] = (int)$info['jdcloud_app_id'];
          $return['app_id'] = (int)$info['jdcloud_app_id'];
          $jdPost['sceneId'] = (int)$info['jdcloud_scene_id'];
          $jdPost['secret'] = $info['jdcloud_scene_secret'];
          // $jdPost['uuid'] = null;
          $jdPost['fingerPrint'] = null;
          // $jdPost['clientVersion'] = null;
          $jdPost['ip'] = $this->dataResource->getClientIp($this->request);
          $jdPost['userAgent'] = $this->dataResource->getUserAgent($this->request);
          $jdPost['clientType'] = $info['jdcloud_client_type'];
          $return['session'] = $captcha->getJdSessionId($jdPost);
          break;
        case 'geetest':
          $return['app_id'] = $info['geetest_id'];
          $return['type'] = $info['geetest_type'];
          $return['style_height'] = $info['geetest_style_height'];
          $return['style_width'] = $info['geetest_style_width'];
          break;
        case 'aliyun':
          $return['app_id'] = $info['aliyun_key_id'];
          $return['style_width'] = $info['aliyun_style_width'];
          break;
        case 'tencent':
          $return['app_id'] = $info['tenc_app_id'];
          break;
      }
    }

    // $return['info'] = $info;
    unset($userInfo, $where, $param, $skip, $time);
    return $this->response->json(Status::CODE_OK, 'success', $return);
  }
  public function verify()
  {
    $valitor = new Validate();
    $valitor->addColumn('captcha_id')->required();
    $valitor->addColumn('token')->required();
    $valitor->addColumn('ip')->optional();
    if ($valitor && !$this->validate($valitor)) {
      throw new ApiException(Status::CODE_BAD_REQUEST, $valitor->getError()->__toString());
    }
    unset($valitor);
    $param = $this->request->all();
    $where['status'] = 1;
    $where['_id'] = $param['captcha_id'];
    $info = mongodb2()->captcha_list->findOne($where);
    $info = json_decode(json_encode($info), true);
    if (empty($info)) {
      return $this->response->json(Status::CODE_OK, 'success', '');
    }
    $newSign = (new \App\Service\Common)->devSignGeneral($param, $info['server_secret']);
    $newSign2 = (new \App\Service\Common)->generateSignature($param, $info['server_secret']);
    if ($param['sign'] != $newSign && $param['sign'] != $newSign2['sign']) {
      $logData['url'] = $this->request->fullUrl();
      $logData['remoteIp'] = $this->dataResource->getClientIp($this->request);
      $logData['user_sign'] = $param['sign'];
      $logData['uid'] = $info['uid'];
      $logData['server_sign'] = $newSign2['sign'];
      $logData['server_query'] = $newSign2['query'];
      queue_push(new SignFailAddJob($logData));
      return $this->response->json(Status::CODE_FAIL, 'sign签名校验失败'.json_encode($param, JSON_UNESCAPED_UNICODE));
    }
    if (isset($info['ak_from']) && $info['ak_from'] == 'platform' && isset($info['ak_id']) && !empty($info['ak_id'])) {
      $akInfo = $this->redisCache->getAk($info['ak_id'],(int)$info['uid']);
      unset($akInfo['_id']);
      $info = array_merge($info, $akInfo);
      unset($akInfo);
    }
    $param['ip'] = (!isset($param['ip']) || empty($param['ip']))?$this->dataResource->getClientIp($this->request): $param['ip'];
    $return = [];
    
    if (!empty($info)) {
      $captcha = new Captcha($info);
      switch ($info['platform']) {
        case 'jdcloud':
          $captcha = new Captcha($info);
          $jdPost['token'] = $param['token'];
          $jdPost['ip'] = $this->dataResource->getClientIp($this->request);
          $jdPost['userAgent'] = $this->dataResource->getUserAgent($this->request);
          $captcha->verifyJdToken($jdPost);
          break;
        case 'geetest':
        $captcha->geetestCheck($param['token'], $param['test']);
          break;
        case 'tencent':
        $captcha->tencentCheck($param['token'], $param['ip']);
          break;
        case 'aliyun':
          $captcha->aliyunCheck($param['token'], $param['ip']);
          break;
      }
    }
    unset($userInfo, $where, $param, $skip, $time);
    return $this->response->json(Status::CODE_OK, 'success', $return);
  }
}
